package l1j.taki;

import java.lang.reflect.Constructor;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
import java.util.logging.Level;

import l1j.server.server.GeneralThreadPool;
import l1j.server.server.IdFactory;
import l1j.server.server.datatables.NpcTable;
import l1j.server.server.model.L1World;
import l1j.server.server.model.L1Location;
import l1j.server.server.model.L1Object;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.serverpackets.S_CharVisualUpdate;
import l1j.server.server.serverpackets.S_MapID;
import l1j.server.server.serverpackets.S_OtherCharPacks;
import l1j.server.server.serverpackets.S_OwnCharPack;
import l1j.server.server.serverpackets.S_RemoveObject;
import l1j.server.server.serverpackets.S_Weather;
import l1j.server.server.templates.L1Npc;

public class ChangeDoor extends TimerTask {
	
	private static Logger _log = Logger.getLogger(ChangeDoor.class.getName());
	
	private Timer _timeHandler = new Timer(true);
	
	private static Random _random = new Random();
	
	private boolean _isOver = false;
	
	private int _startTime = 0;

	private static final int[][] _crack = {
		{ 32863, 32927, 6301},//天空
		{ 32697, 32740, 632} //羅馬
	};
	
	private static ChangeDoor _instance;
	
	public static ChangeDoor getStart() {
		if (_instance == null) {
			_instance = new ChangeDoor();
		}
		return _instance;
	}
	
	public void startCrackTime(){
		ChangeDoor.getStart();
	}
	
	private ChangeDoor() {
		// 開始執行此時間軸
		_timeHandler.schedule(this, 500, 500);
		// 交由線程工廠 處理
		GeneralThreadPool.getInstance().execute(this);
	}

	@Override
	public void run() {
		// 時空裂痕結束
		if (_isOver) {			
			clear();

		}
		_startTime ++;
		switch (_startTime) {			
		case 1*2:
			spawnCrack();
			break;
		case 120*60*2 +120:
			_isOver = true;
			L1World.getInstance().broadcastServerMessage("\\fY【異界傳送門】即將轉換");
			break;

		case 120*60*2 +240:
			_isOver = true;
			break;
		}
	}

	private void clear() {
		_startTime = 0;
		_isOver = false;
		for (L1Object obj : L1World.getInstance().getAllNpcs()) {
			if (obj instanceof L1NpcInstance) {
				L1NpcInstance Cracknpc = (L1NpcInstance) obj;
				if (Cracknpc.getNpcId()== 900005) {
					Cracknpc.deleteMe();
				}
			}
		}
	}

	private void spawnCrack() {
		L1Location crack = null;
		L1Location crack_loc = null;
		int rnd1 = _random.nextInt(2);
		crack = new L1Location(_crack[rnd1][0], _crack[rnd1][1], _crack[rnd1][2]);
		crack_loc = new L1Location(32764, 32913, 613);
		createCrack(crack.getX(), crack.getY(), (short) crack.getMapId(), crack_loc.getX(), crack_loc.getY(), (short) crack_loc.getMapId());
		createCrack(crack_loc.getX(), crack_loc.getY(), (short) crack_loc.getMapId(), crack.getX(), crack.getY(), (short) crack.getMapId());
		String map = "";
		if (_crack[rnd1][2] == 6301)
			map = "天空之城";
		else if (_crack[rnd1][2] == 632)
			map = "羅馬世界";
		L1World.getInstance().broadcastServerMessage("\\fY【異界傳送門】(" + map + ")已於【奇怪的村莊】開啟");
	}
	private void createCrack(int x, int y, short mapId, int to_x, int to_y, short to_mapId) {
		try {
			L1Npc l1npc = NpcTable.getInstance().getTemplate(900005);

			if (l1npc == null) {
				return;
			}

			String s = l1npc.getImpl();
			Constructor<?> constructor = Class.forName("l1j.server.server.model.Instance." + s + "Instance").getConstructors()[0];
			Object aobj[] = { l1npc };
			L1NpcInstance npc = (L1NpcInstance) constructor.newInstance(aobj);

			npc.setId(IdFactory.getInstance().nextId());
			npc.setX(x);
			npc.setY(y);
			npc.setMap(mapId);
			npc.setHomeX(npc.getX());
			npc.setHomeY(npc.getY());
			npc.setHeading(0);

			L1World.getInstance().storeObject(npc);
			L1World.getInstance().addVisibleObject(npc);

			Teleport teleport = new Teleport(npc, to_x, to_y, to_mapId);
			GeneralThreadPool.getInstance().execute(teleport);
		} catch (Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}
	
	public void restartPlayer(L1PcInstance pc, int locx, int locy, short mapid){//移除玩家
		pc.removeAllKnownObjects();
		pc.broadcastPacket(new S_RemoveObject(pc));
		pc.setCurrentHp(pc.getLevel());
		pc.set_food(40);
		pc.setDead(false);
		pc.setStatus(0);
		L1World.getInstance().moveVisibleObject(pc, mapid);
		pc.setX(locx);
		pc.setY(locy);
		pc.setMap((short) mapid);
		pc.sendPackets(new S_MapID(pc.getMapId(), pc.getMap().isUnderwater()));
		pc.broadcastPacket(new S_OtherCharPacks(pc));
		pc.sendPackets(new S_OwnCharPack(pc));
		pc.sendPackets(new S_CharVisualUpdate(pc));
		pc.startHpRegeneration();
		pc.startMpRegeneration();
		pc.sendPackets(new S_Weather(L1World.getInstance().getWeather()));
		if (pc.getHellTime() > 0) {
			pc.beginHell(false);
		}
	}

	class Teleport implements Runnable {
		private L1NpcInstance _npc = null;

		private int _to_x = 0;
		private int _to_y = 0;
		private short _to_mapId = 0;

		public Teleport(L1NpcInstance npc, int to_x, int to_y, short to_mapId) {
			_npc = npc;
			_to_x = to_x;
			_to_y = to_y;
			_to_mapId = to_mapId;
		}

		public void run() {
			try {
				Thread.sleep(1000);
				for (;;) {
					if (_npc._destroyed) {
						return;
					}

					for (L1Object obj : L1World.getInstance().getVisiblePoint(_npc.getLocation(), 1)) {
						if (obj instanceof L1PcInstance) {
							L1PcInstance target = (L1PcInstance) obj;
							L1Location tmp_loc = new L1Location(_to_x, _to_y, _to_mapId);
							L1Location rnd_loc = tmp_loc.randomLocation(1, 5, false);
							L1Teleport.teleport(target, rnd_loc.getX(), rnd_loc.getY(), (short) rnd_loc.getMapId(), target.getHeading(), true);
						}
					}
					Thread.sleep(1000);
				}
			} catch (Exception e) {
				_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			}
		}
	}
}